# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""
字面量发射器

处理各种字面量的代码生成。
"""

from ...ir import IRNode
from ...ir.expressions import IRConstant, IRName
from ..core.emitter import EmitResult, NodeTypeEmitter
from ..core.context import CodeGenContext
from ..configs.names import get_name_mapping


class LiteralEmitter(NodeTypeEmitter):
    """字面量发射器

    处理常量、名称等字面量的代码生成。
    """

    def __init__(self):
        super().__init__([IRConstant, IRName])

    def emit(self, node: IRNode, context: CodeGenContext) -> EmitResult:
        """生成字面量代码"""
        if isinstance(node, IRConstant):
            return self._emit_constant(node, context)
        elif isinstance(node, IRName):
            return self._emit_name(node, context)
        else:
            return EmitResult(code="/* Unknown literal */", precedence=0)

    def _emit_constant(self, node: IRConstant, context: CodeGenContext) -> EmitResult:
        """生成常量代码

        迁移自IRConstant.render方法
        """
        value = node.value

        # 其他类型的常量按正常方式处理
        if isinstance(value, bool):
            code = "true" if value else "false"
        elif isinstance(value, (int, float)):
            code = str(value)
        elif isinstance(value, str):
            # 字符串常量需要转义并加引号
            escaped = (
                value.replace("\\", "\\\\")
                .replace('"', '\\"')
                .replace("\n", "\\n")
                .replace("\t", "\\t")
            )
            code = f'"{escaped}"'
        elif value is None:
            # None 统一生成 nullptr
            # 对于 Optional[T] 类型的参数，C++ 函数会根据 nullptr_t 类型来返回 std::nullopt
            code = "nullptr"
        else:
            code = str(value)

        return EmitResult(code=code, precedence=0)

    def _emit_name(self, node: IRName, context: CodeGenContext) -> EmitResult:
        """生成名称代码"""
        # 获取名称映射
        cpp_name = get_name_mapping(node.id)

        # 特殊处理self -> this
        if node.id == "self":
            cpp_name = "this"

        return EmitResult(code=cpp_name, precedence=0)

    def get_priority(self) -> int:
        """字面量发射器的优先级"""
        return 50  # 较低优先级，让特殊处理器优先
